package com.atguigu.tingshu.account.listener;

import com.atguigu.tingshu.account.service.UserAccountService;
import com.atguigu.tingshu.common.constant.RabbitConstant;
import com.atguigu.tingshu.model.account.UserAccount;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;

// account 消费者
// user作为生产者 当常见新用户的时候，会发送消息给account 消费者
// account 消费者会接收到消息，然后初始化该用户的账户信息
@Component
@Slf4j
public class AccountListener {

    @Autowired
    private UserAccountService userAccountService;

    @RabbitListener(
            bindings = {
                    @QueueBinding(
                            exchange = @Exchange(
                                    value = RabbitConstant.USER_EXCHANGE,
                                    type = ExchangeTypes.TOPIC,
                                    durable = "true"
                            ),
                            value = @Queue(
                                    value = RabbitConstant.USER_REGISTER_QUEUE,
                                    durable = "true"
                            ),
                            key = RabbitConstant.USER_REGISTER_RK
                    )
            }
    )

    public void initAccount(Channel channel, Message message, Long userId) {

        try {
            // 创建账户 初始化账户信息
            userAccountService.saveAccount(userId);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {

            // 第一次出现异常会进行常识重新投递 消费
            if (message.getMessageProperties().isRedelivered()) {

                // 消息多次消费 进入死信队列 或者丢消息
                log.error("count-->消息消费失败。消息：{}, 用户id: {},消息将被抛弃.....", message, userId);
                try {
                    // 拒绝消息
                    channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }

            } else {
                try {
                    // 重新投递 消息
                    log.error("count-->消息消费失败。消息：{}, 用户id: {},正在进行重试......", message, userId);
                    channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }

        }
    }
}
